package com.inspinia.upms.server.controller.upms;

import com.inspinia.auth.rpc.api.AuthService;
import com.inspinia.base.common.model.AjaxResult;
import com.inspinia.base.common.model.ResourcesType;
import com.inspinia.base.pagination.Pager;
import com.inspinia.base.util.CollectionUtil;
import com.inspinia.base.util.StringUtils;
import com.inspinia.upms.common.model.dept.UpmsDept;
import com.inspinia.upms.common.model.org.UpmsOrgDeptVo;
import com.inspinia.upms.common.model.org.UpmsOrgDeptVoType;
import com.inspinia.upms.common.model.org.UpmsOrganization;
import com.inspinia.upms.common.model.org.UpmsOrganizationVo;
import com.inspinia.upms.common.model.post.UpmsPost;
import com.inspinia.upms.rpc.api.UpmsDeptService;
import com.inspinia.upms.rpc.api.UpmsOrganizationService;
import com.inspinia.upms.rpc.api.UpmsPostService;
import com.inspinia.upms.server.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.beans.PropertyEditorSupport;
import java.util.ArrayList;
import java.util.List;

import static com.inspinia.upms.common.model.org.UpmsOrgDeptVoType.dept;

@Controller
@RequestMapping("upms/organization")
public class UpmsOrganizationController extends BaseController {

    private String prefix = "upms/organization/";

    @Autowired
    private UpmsOrganizationService upmsOrganizationService;
    @Resource
    UpmsPostService upmsPostService;
    @Resource
    UpmsDeptService upmsDeptService;
    @Autowired
    private AuthService authService;

    @InitBinder
    public void intiBinder(WebDataBinder binder) {
        binder.registerCustomEditor(ResourcesType.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(ResourcesType.valueOf(Integer.valueOf(text)));
            }
        });
        binder.registerCustomEditor(UpmsOrgDeptVoType.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) throws IllegalArgumentException {
                setValue(UpmsOrgDeptVoType.valueOf(Integer.valueOf(text)));
            }
        });
    }


    /**
     * 获取所有组织机构菜单
     *
     * @return
     */
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String toListPage(Model model) {
        model.addAttribute("resourceType", ResourcesType.values());
        return prefix + "organization-pagination";
    }


    /**
     * 获取所有组织机构菜单数据
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public List<UpmsOrganization> list(UpmsOrganizationVo vo){
        Pager<UpmsOrganization> organizations = upmsOrganizationService.findPage(vo);
        List<UpmsOrganization> list = organizations.getList();
        if (CollectionUtil.isNotEmpty(list)){
            if (StringUtils.isNotBlank(vo.getName())){
                list = findParent(list.get(0),list);
            }
            return list;
        }
//        List<UpmsOrgDeptVo> vos = new ArrayList<>(organizations.size());
//        for (UpmsOrganization org : organizations) {
//            UpmsOrgDeptVo vo = new UpmsOrgDeptVo();
//            BeanUtil.copyProperties(org, vo);
////            vo.setDefaultIcon();
//            vos.add(vo);
//        }
        return new ArrayList<>();
    }

    /**
     * 寻找父节点
     * @param org
     * @param list
     */
    private List<UpmsOrganization> findParent(UpmsOrganization org, List<UpmsOrganization> list){
        UpmsOrganization upmsOrganization = upmsOrganizationService.get(org.getPid());
        list.add(upmsOrganization);
        if (upmsOrganization.getPid()!= null){
            findParent(upmsOrganization, list);
        }
        return list;
    }

    /**
     * 获取所有组织机构菜单数据
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "listOrgAndDept", method = RequestMethod.POST)
    public List<UpmsOrgDeptVo> listOrgAndDept(UpmsOrgDeptVoType treeType) {
        //默认使用部门树
        if (null == treeType) {
            treeType = UpmsOrgDeptVoType.dept;
        }
        return findOrgAndDept4tree(treeType) == null? new ArrayList<>():findOrgAndDept4tree(treeType);
    }

    /**
     * 方法在dubbo中异步调用存在超时
     * @param treeType
     * @return
     */
    public List<UpmsOrgDeptVo> findOrgAndDept4tree(UpmsOrgDeptVoType treeType) {
        //先查找出所有的组织和部门信息。
        List<UpmsOrgDeptVo> orgDeptVos;

        switch (treeType) {
            case org:
                List<UpmsOrganization> orgs = upmsOrganizationService.findAll();
                orgDeptVos = new ArrayList<>(orgs.size());
                //组装树形数据
                for (UpmsOrganization org : orgs) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(org.getId(), org.getName(), UpmsOrgDeptVoType.org, org.getPid());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
            case post:
                //先拼接部门的组织的树
                orgDeptVos = findOrgAndDept4tree(dept);
                List<UpmsPost> posts = upmsPostService.findAll();
                for (UpmsPost post : posts) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(post.getId(), post.getPostName(), UpmsOrgDeptVoType.post, post.getDeptId());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
            default:
                //默认使用部门的树
                List<UpmsDept> departments = upmsDeptService.findAll();
                orgDeptVos = findOrgAndDept4tree(UpmsOrgDeptVoType.org);
                for (UpmsDept dept : departments) {
                    UpmsOrgDeptVo orgDeptVo = new UpmsOrgDeptVo(dept.getId(), dept.getDeptName(), UpmsOrgDeptVoType.dept, dept.getOrgId());
                    orgDeptVos.add(orgDeptVo);
                }
                break;
        }

        return orgDeptVos;
    }
    /**
     * 获取所有组织机构菜单数据
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "listByUser", method = RequestMethod.POST)
    public List listByUser() {
        return authService.findResourcesByUser(getPrincipalId());
    }

    /**
     * 跳转添加页面
     *
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.GET)
    public String goCreate() {
        return prefix + "organization-create";
    }

    /**
     * 跳转修改页面
     *
     * @return
     */
    @RequestMapping(value = "edit", method = RequestMethod.GET)
    public String goEdit() {
        return prefix + "organization-edit";
    }

    /**
     * 创建组织机构
     *
     * @param bean
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public AjaxResult create(@Valid UpmsOrganization bean) {
        boolean bl = upmsOrganizationService.insertByBean(bean);
        AjaxResult ajaxResult = null;
        if(bl){
            ajaxResult = new AjaxResult(true, bean);
        }else {
            ajaxResult = new AjaxResult(false, "机构名称已存在,请重新输入");
        }
        return ajaxResult;
    }

    /**
     * 获取组织机构信息
     *
     * @param id 资源id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "get")
    public AjaxResult findById(Long id) {
        UpmsOrganization bean = upmsOrganizationService.get(id);
        return new AjaxResult(true, bean);
    }

    /**
     * 删除组织机构信息
     *
     * @param id 资源id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public AjaxResult delete(Long id) {
        int delete = upmsOrganizationService.delete(id);
        if (delete > 0) {
            return new AjaxResult(true,"删除成功");
        }
        return new AjaxResult(false, "删除失败,请确认该组织没有被使用");

    }

    /**
     * 编辑组织机构
     *
     * @param bean 资源信息
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "edit", method = RequestMethod.POST)
    public AjaxResult edit(@Valid UpmsOrganization bean) {
        if(null == bean.getCountyId()){
            bean.setCountyId(-1L);
        }
        if(null == bean.getCityId()){
            bean.setCityId(-1L);
        }
        boolean bl = upmsOrganizationService.updateByBean(bean);
        AjaxResult ajaxResult = null;
        if(bl){
            ajaxResult = new AjaxResult(true);
        }else {
            ajaxResult = new AjaxResult(false, "机构名称已存在,请重新输入");
        }
        return  ajaxResult;
    }

    /**
     * 查找用户所在市下面的机构的平级机构
     */
    @RequestMapping(value = "findSameLevelOrgAndCity", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult findSameLevelOrgAndCity() {
        Long userId = getPrincipalId();
        List<UpmsOrganization> orgData = upmsOrganizationService.findSameLevelOrgAndCity(userId);
        return new AjaxResult(true,orgData);
    }

    /**
     * 检查组织机构名是否重复
     *
     * @param name
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "validName", method = RequestMethod.POST)
    public boolean validPhone(String name, Long id, Long pid) {
        return !upmsOrganizationService.validateName(name, id, pid);
    }

    /**
     * 查找用户所在机构的平级机构
     */
    @ResponseBody
    @RequestMapping(value = "findSameLevelOrgs", method = RequestMethod.POST)
    public AjaxResult findSameLevelOrgs() {
        Long userId = getPrincipalId();
        List<UpmsOrganization> orgData = upmsOrganizationService.findSameLevelOrgs(userId);
        return new AjaxResult(true,orgData);
    }

    /**
     * 查询用户所在的下级所有子集
     */
    @ResponseBody
    @RequestMapping(value = "findByParentId", method = RequestMethod.POST)
    public AjaxResult findByParentId() {
        Long userId = getPrincipalId();
        UpmsOrganization org = upmsOrganizationService.findOrgByUserId(userId);
        List<UpmsOrganization> orgData = upmsOrganizationService.findByParentId(org.getId());
        return new AjaxResult(true,orgData);
    }
}
